/* 
*
*  EXAMPLE

    window.addEvent('domready',function() {
        pag = new PageNavigator($$('.pagination'),0,0,{'navpages':4,'elperpage':10});
        pag.addEvent('changepage',function(page,pages,elperpage) { 
            $('page').set('value',page);
            $('itemsperpage').set('value',elperpage);
            callResults();
        });
    });*/


var PageNavigator = new Class({
    /* Events:
        onChangepage(page,pages,elementsPerPage)
       Methods:
        setPage(page)
    */
    Implements: [Options,Events],
    pageElements: null,
    page: 0,
    pages: 0,
    options: { navpages: 2,
               elperpage: 25,
               link: '#{page}',
               events: true }, //{page},{pages},{elperpage}
    
    initialize: function(paginator,page,pages,options) {
        if (typeOf(paginator)=='element') {
            this.pageElements = new Elements(paginator);
        }else{
            this.pageElements = paginator
        }
        this.pages = pages;
        this.pageElement = paginator;
        this.setOptions(options);

        this.setPage(page);
    },

    reset: function(page,count) {
        this.pages = Math.ceil(count/this.options.elperpage);
        this.setPage(page,false);
    },

    setPage: function(page,raise) {
        if (raise==undefined) raise = true;
        //limits
        if (page > this.pages) page = this.pages;
        if (page <= 0) page = 1;
        this.page = parseInt(page);
        this.makePaginator();

        if (raise) this.fireEvent('changepage',[this.page,this.pages,this.options.elperpage]);

        return this.page;
    },

    makeLink:function(page) {
        //parameters
        switch(page) {
            case 'prev': page = this.page-1; break;
            case 'next': page = this.page+1; break;
            case 'first': page = 1; break;
            case 'last': page = this.pages; break;
        }
        //check validity
        if (page<1) page = 1;
        if (page>this.pages) page = this.pages;

        //params       
        var params = {'page':page,'pages':this.pages,'elperpage':this.options.elperpage};
        return this.options.link.substitute(params);
    }.protect(),

    makePaginator: function() {

        var list = new Element('ul');

        var prev = this.addLink(new Element('li',{'class':'prev'}),'prev').inject(list);
        if (this.page <= 1) prev.addClass('disabled');

        var navpages = this.options.navpages>2?this.options.navpages:2;

        var start = this.page-navpages;
        var end = this.page+navpages;
        if (end>this.pages) { start=start-(end-this.pages); end = this.pages; }
        if (start<1) { end=end+(0-start+1); start = 1; }

        if (end>this.pages) { end = this.pages; }
        if (start<1) { start = 1; }

        var gap = 1;
        var first = (start > gap);
        var last = (end < this.pages-gap+1);
        if (first) start+=2;
        if (last) end-=2;
        
        if (first) {
            this.addLink(new Element('li'),1).inject(list);
            new Element('li',{'html':'<a>...</a>','class':'disabled'}).inject(list);
        }

        var range = this.options.navpages*2+1;
        for (var i=0; i<range; i++) {
            var cur = start+i;
            if (cur>end) continue;
            var page = this.addLink(new Element('li'),cur).inject(list);
            if (cur==this.page) page.addClass('active');
        }
        
        if (last) {
            new Element('li',{'html':'<a>...</a>','class':'disabled'}).inject(list);
            this.addLink(new Element('li'),this.pages).inject(list);
        }

        var next = this.addLink(new Element('li',{'class':'next'}),'next').inject(list);
        if (this.page >= this.pages) next.addClass('disabled');

        this.pageElements.forEach(function(el) {
            el.getChildren().destroy();
            var clist = list.clone();
            if (this.options.events) {
                clist.getElements('a[nav:page]').forEach(function(a) {
                    this.makeEvent(a);
                }.bind(this));
            }
            clist.inject(el);
        }.bind(this));
        list.destroy();
    }.protect(),
    
    addLink: function(el,link) {
        var page = link;
        var value = link;
        if (link=='prev') { value = "&larr; Previous"; page = this.page - 1; }
        if (link=='next') { value = "Next &rarr;"; page = this.page + 1; }
        new Element('a',{'href':this.makeLink(link),'html':value,'nav:page':page}).inject(el);
        return el;
    }.protect(),

    makeEvent: function(el) {
         el.addEvent('click',function(e) { 
                                if (!e.target.getParent().hasClass('disabled'))
                                    this.setPage(e.target.getAttribute('nav:page'));
                                else
                                    return false;
                             }.bind(this));
    }.protect()
    
});
